package com.billdowney.service.impl.security;

import java.util.List;
import java.util.Optional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.billdowney.dao.user.UserLoginInfoDao;
import com.billdowney.entity.user.UserLoginInfo;
import com.billdowney.entity.user.UserLoginRecordStatus;
import com.billdowney.security.SecurityConst;
import com.billdowney.service.impl.base.BaseServiceImpl;
import com.billdowney.service.interfaces.user.UserLoginRecordService;
import com.billdowney.util.CommonUtil;

/**
 * spring security实现类
 * 
 * @author 超级小富翁 - BillDowney
 * @date 2019年2月3日 下午7:18:54
 */
@Service
public class UserDetailsServiceImpl extends BaseServiceImpl<UserLoginInfoDao, UserLoginInfo, String>
		implements UserDetailsService {

	@Autowired
	private HttpServletRequest request;
	@Autowired
	private SessionRegistry sessionRegistry;
	@Autowired
	private UserLoginRecordService userLoginRecordService;

	@Resource(type = UserLoginInfoDao.class)
	@Override
	public void setDao(UserLoginInfoDao userLoginInfoDao) {
		super.dao = userLoginInfoDao;
	}

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		UserLoginInfo userLoginInfo = new UserLoginInfo();
		userLoginInfo.setUsername(username);
		Optional<UserLoginInfo> optional = dao.findOne(Example.of(userLoginInfo));
		if (!optional.isPresent()) {
			throw new UsernameNotFoundException("用户名不存在");
		}
		userLoginInfo = optional.get();
		// 剔除之前登录的用户
		List<SessionInformation> sessionsInfo = sessionRegistry.getAllSessions(userLoginInfo, false);
		if (CommonUtil.isNotEmpty(sessionsInfo) && sessionsInfo.size() >= SecurityConst.MAXIMUM_SESSIONS) {
			for (SessionInformation info : sessionsInfo) {
				info.expireNow();
				sessionRegistry.removeSessionInformation(info.getSessionId());
				userLoginRecordService.addUserLoginRecord(request, userLoginInfo,
						UserLoginRecordStatus.userMultipleLogin);
			}
		}
		return userLoginInfo;
	}

}
